package com.hymjweb.demo.hymj.native_bill_manage.controller;

import com.alibaba.fastjson.JSONObject;
import com.hymjweb.demo.framework.cache.service.GlobalCacheService;
import com.hymjweb.demo.framework.result.BaseResultMap;
import com.hymjweb.demo.framework.sys.BaseController;
import com.hymjweb.demo.framework.sys.SysConstant;
import com.hymjweb.demo.framework.util.DataTypeUtil;
import com.hymjweb.demo.framework.util.DateUtil;
import com.hymjweb.demo.framework.util.util.QRCodeUtil;
import com.hymjweb.demo.hymj.basic_data_manage.xt_city.bean.XtCityPojo;
import com.hymjweb.demo.hymj.basic_data_manage.xt_city.service.XtCityService;
import com.hymjweb.demo.hymj.cash_set_manage.bean.BCashSetPojo;
import com.hymjweb.demo.hymj.cash_set_manage.service.BCashSetService;
import com.hymjweb.demo.hymj.customer_manage.contact.bean.BCustomerContactPojo;
import com.hymjweb.demo.hymj.customer_manage.contact.service.BCustomerContactService;
import com.hymjweb.demo.hymj.department_manage.bean.XtDepartmentPojo;
import com.hymjweb.demo.hymj.flight_manage.service.BFlightService;
import com.hymjweb.demo.hymj.native_bill_manage.bean.BNativeBillPojo;
import com.hymjweb.demo.hymj.native_bill_manage.service.BNativeBillService;
import com.hymjweb.demo.hymj.system_maintenance.user.bean.XtUserPojo;
import com.hymjweb.demo.hymj.system_maintenance.user.service.XtUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.*;

@Controller
@RequestMapping("/pages/native_bill_manage")
public class BNativeBillController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(BNativeBillController.class);

    @Autowired
    private XtCityService xtCityService;

    @Autowired
    private BCashSetService bCashSetService;

    @Autowired
    private BNativeBillService bNativeBillService;

    @Autowired
    private BCustomerContactService bCustomerContactService;

    @Autowired
    private BFlightService bFlightService;

    @Autowired
    private XtUserService xtUserService;

    @Autowired
    private GlobalCacheService globalCacheService;

    private String companyName = "航燕敏捷";

    private String companyPhone = "0510-88262448";

    /**
     * 开分单入口，需要设定相应的页需要的参数
     *
     * @return
     */
    @RequestMapping("/createNativeBill")
    public String createNativeBill() throws Exception {

        // 设定相关参数供页面使用
        // 1.营业部所在城市
        XtDepartmentPojo xtDepartmentPojo = this.getLoginUserDepartment();
        String cityId = xtDepartmentPojo.getCityId();
        // 根据cityId获取动城市对象
        XtCityPojo xtCityPojo = xtCityService.fetch(cityId);
        setRequestAttribute("cityId", xtCityPojo.getId());
        setRequestAttribute("cityName", xtCityPojo.getName());

        // 获取当前收银员,要根据时间与部门来锁定收银员
        // 2.当前收银员
        String departmentId = xtDepartmentPojo.getId();
        setRequestAttribute("depId", departmentId);

        // BCashSetPojo casherPojo = bCashSetService.queryCashSetByDeptIdAndTime(departmentId, DateUtil.getNow());

//        if (casherPojo != null) {
//            setRequestAttribute("casherId", casherPojo.getCasherId());
//        } else {
//            throw new Exception("【" + this.getLoginUserDepartment().getName() + "】当前时间无收银员，不能开分单!");
//        }

        // 3.当前登录用户是谁
        setRequestAttribute("loginUserId", this.getLoginUserId());

        // 4.设定开单日期
        setRequestAttribute("openBillDate", DateUtil.dateToStr_yyyy_MM_dd(DateUtil.getSysDate()));

        // 5.设定操作类型
        setRequestAttribute("opType", SysConstant.OPER_ADD);

        return "pages/native_bill_manage/createNativeBill";
    }

    /**
     * 查询分单列表
     *
     * @return
     */
    @RequestMapping("/nativeBillList")
    public String nativeBillList() {
        return "pages/native_bill_manage/nativeBillList";
    }


    /**
     * 提货点对账
     *
     * @return
     */
    @RequestMapping("/pickUpReconciliation")
    public String pickUpReconciliation() {
        return "pages/native_bill_manage/pickUpReconciliation";
    }


    @RequestMapping("/queryBill")
    @ResponseBody
    public Object queryBill(@RequestParam(required = false) Map param) {
        return bNativeBillService.getPageList(param);
    }


    @RequestMapping("/queryBillReceiveCustomerByDeliveryCustomerId")
    @ResponseBody
    public Object queryBillReceiveCustomerByDeliveryCustomerId(@RequestParam(required = false) Map param) throws Exception {
        if (param == null || param.isEmpty()) {
            throwException("收货人查询参数错误!");
        }
        return bNativeBillService.queryBillReceiveCustomerByDeliveryCustomerId(param);
    }

    @RequestMapping("/getBNativeBillPojoByCnd")
    @ResponseBody
    public Object getBNativeBillPojoByCnd(@RequestParam(required = true) Map param) {
        return bNativeBillService.getBNativeBillPojoByCnd(param);
    }


    @RequestMapping("/savePickupDriverFee")
    @ResponseBody
    public Object savePickupDriverFee(@RequestBody(required = false) JSONObject param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单提货费填写参数异常!");
        }

        String id = DataTypeUtil.toNotNullString(param.get("id"));
        Long pickupDriverFee = DataTypeUtil.toLong(param.get("pickupDriverFee"),-1L);
        String pickupDriverName = DataTypeUtil.toNotNullString(param.get("pickupDriverName"));

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("分单提货费保存成功!");

        int affectRows = bNativeBillService.savePickupDriverFee(id,pickupDriverFee,pickupDriverName);

        if(affectRows>SysConstant.INT_ZERO){
            baseResultMap.setOk(false);
            baseResultMap.setMessage("分单提货费保存失败!");
        }

        return baseResultMap;
    }


    /**
     * 打印日报处理
     *
     * @param param
     * @return
     * @throws Exception
     */
    @RequestMapping("/dailyReport")
    @ResponseBody
    public Object dailyReport(@RequestBody(required = false) JSONObject param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单日报打印参数错误!");
        }

        Map<String, Object> paramMap = DataTypeUtil.jsonObjectToMap(param);
        List<BNativeBillPojo> bNativeBillPojoList = bNativeBillService.getDailyReportList(paramMap);

        BaseResultMap baseResultMap = new BaseResultMap();
        if (bNativeBillPojoList == null || bNativeBillPojoList.isEmpty()) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("日报为空");
            return baseResultMap;
        }

        String printOne = this.getLoginUser().getName();
        String printDate = DateUtil.getStringDateShort();
        String printDepartment = this.getLoginUserDepartment().getName();

        Map<String, Object> map = new HashMap<>();
        map.put("printOne", printOne);
        map.put("printDepartment", printDepartment);
        map.put("printDate", printDate);
        map.put("printData", bNativeBillPojoList);

        baseResultMap.setOk(true);
        baseResultMap.setData(map);

        return baseResultMap;
    }


    @RequestMapping("/showUpdateBill")
    public String showUpdateBill(String opType, String id) throws Exception {
        if (DataTypeUtil.isEmptyStr(opType) || DataTypeUtil.isEmptyStr(id)) {
            throwException("分单加载参数异常!");
        }
        // 查询出要显示的分单对象
        BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(id);
        if (bNativeBillPojo == null) {
            throwException("分单加载失败!");
        }
        // 根据业务员id检索出业务员对象
        XtUserPojo salemanUserPojo = xtUserService.findObjectById(bNativeBillPojo.getDeliveryCustomerSalemanId());
        if (salemanUserPojo == null) {
            throwException("分单收货人业务员加载失败!");
        }
        // 查询出要给联系人列表绑定的数据
        List<BCustomerContactPojo> contactPojos = bCustomerContactService.queryContactByCustomerId(bNativeBillPojo.getDeliveryCustomerId());
        if (contactPojos == null || contactPojos.isEmpty()) {
            throwException("分单收货客户联系人列表加载失败!");
        }

        // 查询出航班列表要绑定的数据
        // 构造航班查询条件
        Map<String, Object> param = new HashMap<>();
        param.put("cityId", bNativeBillPojo.getDestCityId());
        param.put("airlinesId", bNativeBillPojo.getAirlinesId());
        param.put("flightDate", DateUtil.dateToStr_yyyy_MM_dd(bNativeBillPojo.getFlightDate()));
        List<Map<String, Object>> bFlightList = bFlightService.queryFlightNoListByDropCnd(param);
        // 空运的才检测航班
        if(bNativeBillPojo.getTransportSpeciesId().longValue() == SysConstant.XT_DIC_TRANSPORT_SPECIES.AIR.getId()){
            if (bFlightList == null || bFlightList.isEmpty()) {
                throwException("分单航班列表加载失败!");
            }
        }

        setRequestAttribute("bNativeBillPojo", objectToJSONObject(bNativeBillPojo));
        setRequestAttribute("salemanName", salemanUserPojo.getName());
        setRequestAttribute("contactPojos", objectToJSONObject(contactPojos));
        setRequestAttribute("bFlightList", objectToJSONObject(bFlightList));

        setRequestAttribute("opType", opType);

        return "pages/native_bill_manage/createNativeBill";
    }

    @RequestMapping("/addNativeBill")
    @ResponseBody
    public Object addNativeBill(@RequestBody(required = true) JSONObject billJsonObj) throws Exception {
        if (billJsonObj == null || billJsonObj.isEmpty()) {
            throwException("添加分单参数错误");
        }

        // 将json对象转为Java对象
        BNativeBillPojo pojo = bNativeBillService.convertJSONObjToJavaObj(billJsonObj, SysConstant.OPER_ADD);
        if (pojo == null) {
            throwException("添加分单对象转换失败");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("添加分单成功!");

        // 保存转换后的结果
        int affectRows = bNativeBillService.addNativeBill(pojo);

        if (affectRows == BNativeBillService.NATIVE_BILL_EXSIT) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("[" + pojo.getId() + "] 分单号已经存在不能重复添加!");
        } else if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("添加分单失败!");
        }

        return baseResultMap;
    }

    @RequestMapping("/updateNativeBill")
    @ResponseBody
    public Object updateNativeBill(@RequestBody(required = true) JSONObject billJsonObj) throws Exception {

        if (billJsonObj == null || billJsonObj.isEmpty()) {
            throwException("更新分单参数错误");
        }

        // 将json对象转为Java对象
        BNativeBillPojo pojo = bNativeBillService.convertJSONObjToJavaObj(billJsonObj, SysConstant.OPER_UPDATE);
        if (pojo == null) {
            throwException("更新分单对象转换失败");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("更新分单成功!");

        // 保存转换后的结果
        int affectRows = bNativeBillService.updateNativeBill(pojo);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("更新分单失败!");
        }

        return baseResultMap;
    }


    @RequestMapping("/updateSaveNativeBill")
    @ResponseBody
    public Object updateSaveNativeBill(@RequestBody(required = true) JSONObject billJsonObj) throws Exception {

        if (billJsonObj == null || billJsonObj.isEmpty()) {
            throwException("更新分单参数错误");
        }

        // 将json对象转为Java对象
        BNativeBillPojo pojo = bNativeBillService.convertJSONObjToJavaObj(billJsonObj, SysConstant.OPER_UPDATE);

        if (pojo == null) {
            throwException("更新分单对象转换失败");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("更新分单成功!");

        // 保存转换后的结果
        int affectRows = bNativeBillService.updateSaveNativeBill(pojo);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("更新分单失败!");
        }

        return baseResultMap;
    }


    /**
     * 分单作废
     *
     * @param param
     * @return
     */
    @RequestMapping("/cancelNativeBill")
    @ResponseBody
    public Object cancelNativeBill(@RequestBody(required = true) Map param) throws Exception {
        if (param == null || param.size() == 0) {
            throwException("分单作废参数错误!");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("分单作废成功!");

        // {billIds:cancelBillIds}
        int affectRows = bNativeBillService.cancelNativeBill(param);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("分单作废失败!");
        }
        return baseResultMap;
    }

    /**
     * 分单删除，参数形式为 id1,id2,id3
     *
     * @param param
     * @return
     */
    @RequestMapping("/deleteNativeBillByBillIds")
    @ResponseBody
    public Object deleteNativeBillByBillIds(@RequestBody(required = true) Map param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单删除参数错误!");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("分单删除成功!");

        // {billIds:canDeleteBillIds}
        int affectRows = bNativeBillService.deleteNativeBillByBillIds(param);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("分单删除失败，请重试!");
        }
        return baseResultMap;
    }


    /**
     * 分单对账状态修改
     *
     * @param param
     * @return
     * @throws Exception
     */
    @RequestMapping("/changeAccountCheckStatus")
    @ResponseBody
    public Object changeAccountCheckStatus(@RequestBody(required = true) Map param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单对账参数错误!");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("分单对账成功!");


        // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus}
        int affectRows = bNativeBillService.changeAccountCheckStatus(param);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("分单对账失败!");
        }
        return baseResultMap;
    }


    /**
     * 分单代理送货费对账状态修改
     *
     * @param param
     * @return
     * @throws Exception
     */
    @RequestMapping("/changeAgentDeliveryChargeAccountCheckStatus")
    @ResponseBody
    public Object changeAgentDeliveryChargeAccountCheckStatus(@RequestBody(required = true) Map param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单代理送货费对账参数错误!");
        }

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage("分单代理送货费对账状态修改成功!");


        // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus}
        //int affectRows = bNativeBillService.changeAccountCheckStatus(param);
        int affectRows = bNativeBillService.changeAgentDeliveryChargeAccountCheckStatus(param);

        if (affectRows <= SysConstant.INT_ZERO) {
            baseResultMap.setOk(false);
            baseResultMap.setMessage("分单代理送货费对账状态修改失败!");
        }
        return baseResultMap;
    }


    @RequestMapping("/generateBillLabel")
    @ResponseBody
    public Object generateBillLabel(String billId, Integer startIndex, Integer endIndex) throws Exception {

        if (DataTypeUtil.isEmptyStr(billId) || startIndex == null || endIndex == null) {
            throwException("生成打印分单标签参数错误!");
        }


        if (endIndex < startIndex) {
            Integer tempIndex = startIndex;
            startIndex = endIndex;
            endIndex = tempIndex;
        }

        // 根据分单号获取分单信息
        BNativeBillPojo nativeBillPojo = bNativeBillService.getBNativeBillPojoById(billId);

        if (nativeBillPojo == null) {
            throwException("根据分单ID获取分单对象失败!!");
        }

        String cityId = nativeBillPojo.getCityId();
        String destCityId = nativeBillPojo.getDestCityId();
        Long transportSpeciesId = nativeBillPojo.getTransportSpeciesId();

        // 始发站
        String cityIdName = globalCacheService.getNameByCacheNameAndId(SysConstant.CACHE_XT_CITY, cityId);
        // 目的站
        String destCityIdName = globalCacheService.getNameByCacheNameAndId(SysConstant.CACHE_XT_CITY, destCityId);
        // 运输方式
        String transportSpeciesIdName = globalCacheService.getNameByCacheNameAndId(SysConstant.CACHE_XT_DIC, transportSpeciesId + "");
        // 收货人
        String receiveCustomerName = nativeBillPojo.getReceiveCustomerName() + "/" + nativeBillPojo.getReceiveCustomerPhone();
        // 总件数
        Integer totalNumber = nativeBillPojo.getTotalNumber();

        String flightNoName = nativeBillPojo.getFlightName();
        String flightDate = DateUtil.changeStrDate(nativeBillPojo.getFlightDate(), "MM-dd");
        String flightPlanTime = nativeBillPojo.getPlanTakeOffTime();

        List<Map<String, Object>> mapList = new ArrayList<>();

        int totalValue = 0;
        for (int i = startIndex; i <= endIndex; i++) {
            totalValue++;
            Map<String, Object> objMap = new HashMap<>();
            objMap.put("companyName", this.companyName);
            objMap.put("companyPhone", this.companyPhone);
            objMap.put("billId", billId);
            objMap.put("transportSpeciesIdName", transportSpeciesIdName);
            objMap.put("cityIdName", cityIdName);
            objMap.put("destCityIdName", destCityIdName);
            objMap.put("receiveCustomerName", receiveCustomerName);
            objMap.put("totalNumber", totalNumber);
            objMap.put("sequence", i);
            objMap.put("flightNoName", flightNoName);
            objMap.put("flightDate", flightDate);
            objMap.put("flightPlanTime", flightPlanTime);
            String content = billId + ":" + flightNoName + ":" + flightDate + ":" + flightPlanTime + ":" + totalNumber + ":" + i;
            objMap.put("content", content);
            objMap.put("qrcodeUrl", "/pages/native_bill_manage/createLabelQrCode?content=" + content + "&qrCodeSize=300");
            mapList.add(objMap);
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("total", totalValue);
        resultMap.put("data", mapList);

        return resultMap;
    }

    @GetMapping("/createLabelQrCode")
    public void createLabelQrCode(String content, int qrCodeSize, HttpServletResponse resp) throws Exception {

        // Set to expire far in the past.
        resp.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        resp.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        resp.setHeader("Pragma", "no-cache");

        resp.setContentType("image/jpeg");

        BufferedImage bi = QRCodeUtil.createQrCode(content, qrCodeSize);

        ServletOutputStream out = resp.getOutputStream();

        ImageIO.write(bi, "jpg", out);
        out.close();
    }



    /**
     * 分单代理对账处理
     * @param upLoadFileData
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/accountFileUploadAncCheck", method = RequestMethod.POST)
    @ResponseBody
    public Object accountFileUploadAncCheck(MultipartFile upLoadFileData) throws Exception {

        if (upLoadFileData == null) {
            throwException("对账文件上传参数错误！");
        }

        String resultMsg = bNativeBillService.accountFileUploadAncCheck(upLoadFileData);

        BaseResultMap baseResultMap = new BaseResultMap();
        baseResultMap.setOk(true);
        baseResultMap.setMessage(resultMsg.length()==0?"对账成功!":resultMsg);

        return baseResultMap;
    }

}
